home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
GL
/
newton
/
play.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
12KB
|
620 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* The main loop of Newton (event handling and stuff)
* Yossi Friedman, 1988
*/
#include <stdio.h>
#include <gl.h>
#include <device.h>
#include "config.h"
#include "newton.h"
#include "windows.h"
#include "slider.h"
static int playing;
/* values for mouse_buttons */
#define LEFT_DOWN 0x010000
#define MIDDLE_DOWN 0x000100
#define RIGHT_ROWN 0x000001
#define LEFT_UP 0x000101
#define MIDDLE_UP 0x010001
#define RIGHT_UP 0x010100
static int spin_mode = SPIN_MODE_DEFAULT;
#define SPIN_FRAME_ACTION 1
extern int auto_mode;
void do_inputchange(short val);
void do_redraw(short val);
void do_winquit(short val);
void do_winfreeze(short val);
void do_menu();
play()
{
short dev, val;
int mouse_buttons = 0;
int spin_frame_count = 0;
short omx, omy, nmx, nmy;
#ifdef STATISTICS
# define TIMES 100
long genesis;
int frame_count = 0;
#endif /* STATISTICS */
/* window manager events */
qdevice(INPUTCHANGE);
qdevice(REDRAW);
qdevice(WINQUIT);
qdevice(WINFREEZE);
qdevice(WINTHAW);
/* user events */
qdevice(ESCKEY);
qdevice(LEFTMOUSE);
qdevice(MIDDLEMOUSE);
qdevice(RIGHTMOUSE);
#ifdef STATISTICS
time(&genesis);
#endif /* STATISTICS */
/*
* initialization. order matters.
*/
initialize_models();
initialize_menus();
for (playing = 1; playing;) {
if (auto_mode) {
spin_mode = 1;
start_gravity();
}
/* check events */
while(qtest()) {
dev=qread(&val);
/*
* handle window manager events separately
*/
switch (dev) {
case INPUTCHANGE:
do_inputchange(val);
continue;
case REDRAW:
do_redraw(val);
continue;
case WINQUIT:
do_winquit(val);
continue;
case WINFREEZE:
do_winfreeze(val);
continue;
case WINTHAW:
/* is supposed to be handled by do_winfreeze */
fprintf(stderr, "newton: Unexpected WINTHAW (val = %d)\n", val);
continue;
}
/*
* handle user events
*/
/* see if it is a slider event */
if (current_window && current_window->sid >= 0) {
if (slider_event(current_window->sid, dev, val) == 0)
close_current_window();
continue;
}
/*
* main window events
*/
switch(dev) {
case ESCKEY:
if (!val)
playing = 0;
break;
case LEFTMOUSE:
if (val) {
build_model(0);
stop_gravity();
omx = getvaluator(MOUSEX);
omy = getvaluator(MOUSEY);
mouse_buttons |= LEFT_DOWN;
}
else {
start_gravity();
mouse_buttons &= LEFT_UP;
}
break;
case MIDDLEMOUSE:
if (val) {
omx = getvaluator(MOUSEX);
omy = getvaluator(MOUSEY);
mouse_buttons |= MIDDLE_DOWN;
}
else
mouse_buttons &= MIDDLE_UP;
break;
case RIGHTMOUSE:
if (val)
do_menu();
break;
default:
fprintf(stderr, "newton: Unknown device event (dev = %d, val = %d)\n", dev, val);
break;
}
}
if (current_window && current_window->sid >= 0)
do_slider(current_window->sid);
if (mouse_buttons) {
nmx = getvaluator(MOUSEX);
nmy = getvaluator(MOUSEY);
reorient(mouse_buttons, 2*(nmx - omx), 2*(nmy - omy));
omx = nmx;
omy = nmy;
}
if (spin_mode && ++spin_frame_count == SPIN_FRAME_ACTION) {
spin_frame_count = 0;
reorient(
MIDDLE_DOWN,
(getvaluator(MOUSEX) - 640)/6,
(getvaluator(MOUSEY) - 512)/5
);
}
draw_everything();
iterate();
#ifdef STATISTICS
if ((++frame_count % TIMES) == 0)
printf("Average: %f frames per second\n",
(float) frame_count / (float)(time(0) - genesis));
#endif /* STATISTICS */
}
}
/*
* window manager event handlers
*/
void
do_inputchange(short val)
{
if (val == 0) {
current_window = NULL;
return;
}
/* search which window was entered */
for (
current_window = windows;
current_window != NULL;
current_window = current_window->next
)
if (current_window->wid == val)
break;
/*
if (current_window == NULL)
fprintf(stderr, "newton: Unidentified INPUTCHANGE (val = %d)\n", val);
*/
}
void
do_redraw(short val)
{
struct window *wp;
long tmp_wid;
long size[2];
/* find out which window has to be redrawn */
for (wp = windows; wp != NULL; wp = wp->next)
if (wp->wid == val)
break;
if (wp == NULL) {
fprintf(stderr, "newton: Unidentified REDRAW (val = %d)\n", val);
return;
}
/* is it a slider? */
if (wp->sid >= 0)
(void) slider_event(wp->sid, REDRAW, val);
else {
tmp_wid = winget();
winset(wp->wid);
reshapeviewport();
if (tmp_wid != -1)
winset(tmp_wid);
}
/* get new corners */
tmp_wid = winget();
winset(wp->wid);
getorigin(&(wp->bot_left[X]), &(wp->bot_left[Y]));
getsize(&size[X], &size[Y]);
wp->top_right[X] = wp->bot_left[X] + size[X];
wp->top_right[Y] = wp->bot_left[Y] + size[Y];
if (tmp_wid != -1)
winset(tmp_wid);
}
void
do_winquit(short val)
{
struct window *wp;
long tmp_wid;
/* find out which window was quit */
for (
current_window = windows;
current_window != NULL;
current_window = current_window->next
)
if (current_window->wid == val)
break;
if (current_window == NULL) {
fprintf(stderr, "newton: Unidentified WINQUIT (val = %d)\n", val);
return;
}
/* is it a slider? */
if (current_window->sid >= 0) {
(void)slider_event(current_window->sid, WINQUIT, val);
close_current_window();
}
else
playing = 0;
}
void
do_winfreeze(short val)
{
struct window *stowed, *wp;
short dev;
int i;
extern void close_model_window(long);
/*
* -------------------- F R E E Z I N G --------------------
*/
/* find out which window was stowed */
for (stowed = windows; stowed != NULL; stowed = stowed->next)
if (stowed->wid == val)
break;
if (stowed == NULL) {
fprintf(stderr, "newton: Unindentified WINFREEZE (val = %d)\n", val);
return;
}
/* close all windows except for the stowed one */
for (wp = windows; wp != NULL; wp = wp->next)
if (wp != stowed)
if (wp->sid >= 0)
close_slider(wp->sid);
else
close_model_window(wp->wid);
#ifdef MP
/* block all the slave processes */
for (i = 1; i < nproc; i++)
blockproc(slave_pid[i]);
#endif /* MP */
/* wait for a WINTHAW */
while ((dev = qread(&val)) != WINTHAW)
/* printf("do_winfreeze: got dev = %d, val = %d\n", dev, val) */
;
/*
* -------------------- T H A W I N G --------------------
*/
/* open all windows that need to be opened */
for (wp = windows; wp != NULL; wp = wp->next)
if (wp != stowed) {
prefposition(wp->bot_left[X], wp->top_right[X],
wp->bot_left[Y], wp->top_right[Y]);
if (wp->sid >= 0)
wp->wid = open_slider(wp->sid);
else
wp->wid = open_model_window("newton");
}
else
if (wp->sid >= 0)
slider_event(wp->sid, REDRAW, wp->wid);
#ifdef MP
/* unblock all slave processes */
for (i = 1; i < nproc; i++)
unblockproc(slave_pid[i]);
#endif /* MP */
find_current_window();
}
initialize_sliders()
{
struct slider *sp;
for (sp = sliders; sp < end_sliders; sp++)
sp->sid = define_slider("Newton", sp->title, sp->lo, sp->hi, sp->dflt, sp->fun);
}
static int
models_menu,
physics_menu,
model_draw_menu,
wall_draw_menu,
main_menu;
initialize_menus()
{
char menu_buf[MAX_MENU_ITEMS*MAX_MENU_ITEM_LEN];
char buf[MAX_MENU_ITEM_LEN], *p, *q;
int i;
/* make the models menu */
for (p = menu_buf, i = 0; model_names + i != end_model_names; i++) {
sprintf(buf,
(i == 0)? "Models %%t|%s %%x%d": "|%s %%x%d",
model_names[i], 101 + i);
for (q = buf; *q; *p++ = *q++)
;
}
*p = 0;
models_menu = defpup(menu_buf);
/* make the physics menu */
for (p = menu_buf, i = 0; i < end_sliders - sliders; i++) {
sprintf(buf,
(i == 0)? "Physics %%t|%s %%x%d": "|%s %%x%d",
sliders[i].title, 201 + i);
for (q = buf; *q; *p++ = *q++)
;
}
*p = 0;
physics_menu = defpup(menu_buf);
/* make the model draw menu */
model_draw_menu = defpup(
#ifdef HAS_BLENDING
"Model Display %t|flat surfaces %x301|smooth surfaces %x302|springs %x303|toggle translucency %x304|toggle surfaces+springs %x305|Bermuda %x306"
#else /* HAS_BLENDING */
"Model Display %t|flat surfaces %x301|smooth surfaces %x302|springs %x303|toggle surfaces+springs %x305|Bermuda %x306"
#endif /* HAS_BLENDING */
);
/* make the wall draw menu */
wall_draw_menu = defpup("Room Display %t|lighted walls w/ shadows %x401|lighted walls w/o shadows %x402|pinball walls %x403");
/* force main menu to be generated */
main_menu = 0;
}
void
do_menu()
{
int val;
struct window *wp;
int sid;
if (main_menu == 0) {
main_menu = defpup("Newton %t| models %m|physics %m|model display %m|room display %m",
models_menu, physics_menu, model_draw_menu, wall_draw_menu);
addtopup(main_menu, spin_mode? "spin mode off": "spin mode on");
addtopup(main_menu, "exit");
}
val = dopup(main_menu);
if (val > 400)
/* wall draw menu */
switch (val) {
case 401:
draw_wall = draw_lighted_wall;
shadows_too = 1;
break;
case 402:
draw_wall = draw_lighted_wall;
shadows_too = 0;
break;
case 403:
draw_wall = draw_pinball_wall;
break;
}
if (val > 300)
/* model draw menu */
switch (val) {
case 301:
draw_model = draw_flat_surfs;
if (mode != RGB) {
mode = RGB;
RGBmode();
gconfig();
}
break;
case 302:
draw_model = draw_smooth_surfs;
if (mode != RGB) {
mode = RGB;
RGBmode();
gconfig();
}
break;
case 303:
draw_model = draw_springs;
if (mode != RGB) {
mode = RGB;
RGBmode();
gconfig();
}
break;
#ifdef HAS_BLENDING
case 304:
alpha_blended = 1 - alpha_blended;
break;
#endif /* HAS_BLENDING */
case 305:
springs_too = 1 - springs_too;
break;
case 306:
draw_model = draw_flat_surfs;
if (mode != COLOR_MAP) {
mode = COLOR_MAP;
cmode();
gconfig();
}
break;
}
else
if (val > 200) {
/* physics menu */
if (&sliders[val - 201] >= end_sliders) {
fprintf(stderr, "newton: Unknown physics menu selection\n");
return;
}
sid = sliders[val - 201].sid;
for (wp = windows; wp != NULL; wp = wp->next)
if (wp->sid == sid) {
/* window already open */
(void) open_slider(sid);
break;
}
if (wp == NULL)
new_window(open_slider(sid), sid);
find_current_window();
}
else
if (val > 100) {
/* models menu */
model_index = val - 101;
build_model(1);
stop_gravity();
}
else
/* main menu */
switch (val) {
case -1:
break;
case 5:
spin_mode = (spin_mode == 0);
/* force regeneration of main menu */
freepup(main_menu);
main_menu = 0;
break;
case 6:
playing = 0;
break;
default:
fprintf(stderr, "newton: Unknown menu selection (%d)\n", val);
break;
}
}
reorient(mouse_buttons, dx, dy)
int mouse_buttons;
int dx, dy;
{
if (mouse_buttons & LEFT_DOWN) {
rotate_model((Angle) dx, 'Y');
rotate_model((Angle)-dy, 'X');
}
if (mouse_buttons & MIDDLE_DOWN) {
rotate_graphics((Angle) dx, 'Y');
rotate_physics ((Angle)-dx, 'Y');
rotate_graphics((Angle)-dy, 'X');
rotate_physics ((Angle) dy, 'X');
}
}